<?php

namespace Model;

require_once("Helper/FormValidator.php");

class TopicList
{
		//Privata strängar
		private $db = NULL;
        private $dbt = NULL;
		
		//Konstrukterar databas & DBtabell instans
        public function __construct(Database $db) 
        {
                $this->db =$db;
				$this->dbt = new \Model\DBTables();	
        }

		//Hämtar samtliga Topic-rader från databasen
		//Returnerar array med topic-objekt
		public function GetAllTopics()
		{
			$sql = "SELECT t.*, u.name, COUNT(p.topicId) AS postCount
					FROM ". $this->dbt->topicTable ." AS t
					INNER JOIN ". $this->dbt->userTable ." AS u
					ON t.userId = u.userId 
					LEFT OUTER JOIN ". $this->dbt->postTable ." AS p
					ON t.topicId = p.topicId
					GROUP BY t.topicId
					ORDER BY t.date DESC";
				
			$stmt = $this->db->Prepare($sql);
			
			$stmt = $this->db->Select($stmt);
			
			if($stmt->bind_result($topicId, $userId, $header, $date, $content, $userName, $postCount) == FALSE)
			{
				throw new \Exception($this->mysqli->error);
			}	
						
			$ret = new TopicArray();
			
			while ($stmt->fetch())
			{
				$topic = new Topic($topicId, $userId, $header, $date, $content, $userName, $postCount);
				$ret->add($topic);
			}
			
			$stmt->close();
			
			return $ret;
						
		}

		//Hämtar de fem topic-rader som har högst antal Posts kopplade till sig
		//Returnerar array med topic-objekt		
		public function GetTopFiveTopics()
		{
			$sql = "SELECT t.*, u.name, COUNT(p.topicId) AS postCount
					FROM ". $this->dbt->topicTable ." AS t 
					INNER JOIN ". $this->dbt->userTable ." AS u
					ON t.userId = u.userId
					LEFT OUTER JOIN ". $this->dbt->postTable ." AS p
					ON t.topicId = p.topicId
					GROUP BY t.topicId
					ORDER BY postcount DESC
					LIMIT 5";
				
			$stmt = $this->db->Prepare($sql);
			
			$stmt = $this->db->Select($stmt);
			
			if($stmt->bind_result($topicId, $userId, $header, $date, $content, $userName, $postCount) == FALSE)
			{
				throw new \Exception($this->mysqli->error);
			}	
						
			$ret = new TopicArray();
			
			while ($stmt->fetch())
			{
				$topic = new Topic($topicId, $userId, $header, $date, $content, $userName, $postCount);
				$ret->add($topic);
			}
			
			$stmt->close();
			
			return $ret;
						
		}		
		
		//Retunerar ett topic-objekt
		public function GetTopic($topicId)
		{
			$sql = "SELECT t.*, u.name, COUNT(p.topicId) AS postCount
					FROM ". $this->dbt->topicTable ." AS t
					LEFT OUTER JOIN ". $this->dbt->postTable ." AS p
					ON t.topicId = p.topicId
					INNER JOIN ". $this->dbt->userTable ." AS u
					ON t.userId = u.userId 
					WHERE t.topicId =?
					GROUP BY t.topicId";
					
			$stmt = $this->db->Prepare($sql);		
			
			$stmt->bind_param("i", $topicId);
			
			$stmt = $this->db->Select($stmt);
			
			if($stmt->bind_result($topicId, $userId, $header, $date, $content, $userName, $postCount) == FALSE)
			{
				throw new \Exception($this->mysqli->error);
			}	
			
			$ret = NULL;
			
			if($stmt->fetch())
			{
				$ret = new Topic($topicId, $userId, $header, $date, $content, $userName, $postCount);
			}
			
			$stmt->close();
			
			return $ret;			
						
		}

		//Returnerar en array med topic-objekt tillhörande medskickat userId		
		public function GetTopicsByUserId($userId)
		{
			$sql = "SELECT t.*, u.name, COUNT(p.topicId) AS postCount
					FROM ". $this->dbt->topicTable ." AS t
					INNER JOIN ". $this->dbt->userTable ." AS u
					ON t.userId = u.userId
					LEFT OUTER JOIN ". $this->dbt->postTable ." AS p
					ON t.topicId = p.topicId
					WHERE t.userId =? 
					GROUP BY t.topicId					
					ORDER BY t.date DESC";
				
			$stmt = $this->db->Prepare($sql);
			
			$stmt->bind_param("i", $userId);
			
			$stmt = $this->db->Select($stmt);
			
			if($stmt->bind_result($topicId, $userId, $header, $date, $content, $userName, $postCount) == FALSE)
			{
				throw new \Exception($this->mysqli->error);
			}	
						
			$ret = new TopicArray();
			
			while ($stmt->fetch())
			{
				$topic = new Topic($topicId, $userId, $header, $date, $content, $userName, $postCount);
				$ret->add($topic);
			}
			
			$stmt->close();
			
			return $ret;			
		}

		//Returnerar topicId på det senast skapade topic-objektet
		public function GetLastAddedTopicId()
		{
			$sql = "SELECT MAX(topicId)
					FROM ". $this->dbt->topicTable;
					
			$stmt = $this->db->Prepare($sql);		
			
			$ret = $this->db->SelectSingleValue($stmt);
			
			return $ret;				
		}

		//Returnerar TRUE vid lyckat skapande av nytt topic	
		public function AddTopic($userId, $header, $content) 
		{						
			$sql = "INSERT INTO ". $this->dbt->topicTable ." (userId, header, content) VALUES (?,?,?)";  
			
			$stmt = $this->db->Prepare($sql); 

			$stmt->bind_param("iss", $userId, $header, $content);			      
			
			$exec = $this->db->Execute($stmt);
			
			return TRUE;
		}

		//Returnerar TRUE vid lyckad editering av ett Topic	
		public function EditTopic($header, $content, $topicId)
		{
			$sql = "UPDATE ". $this->dbt->topicTable .
					" SET header=?, content=?
					WHERE topicId=?";  
			
			$stmt = $this->db->Prepare($sql); 

			$stmt->bind_param("ssi", $header, $content, $topicId);			      
			
			$exec = $this->db->Execute($stmt);
			
			return TRUE;			
		}
	
		//Returnerar TRUE vid lyckad borttagning av ett Topic		
		public function DeleteTopic($topicId)
		{
			$sql = "DELETE t.*, p.*
					FROM ". $this->dbt->topicTable ." AS t
					LEFT JOIN ". $this->dbt->postTable ." as p
					ON t.topicId = p.topicId
					WHERE t.topicId=?";
			
			$stmt = $this->db->Prepare($sql); 

			$stmt->bind_param("i", $topicId);			      
			
			$exec = $this->db->Execute($stmt);
			
			return TRUE;			
		}
		
		//Anropar "FormValidator" för validering av topicinnehåll
		//Returnerar array innehållande felmeddelanden		
		public function ValidateTopicInput($header, $content)
		{
			$fv = new \FormValidator();
			
			$fv->ValidateArticleHeader($header);
			$ret = $fv->ValidateLargeContent($content);

			return $ret;
		}		
		
		//AUTOMATISK TESTKLASS				
		public static function Test(TopicList $tl)
		{
			//Testar GetAllTopics			
			$allTopics = $tl->GetAllTopics();
			
			if(get_class($allTopics) != "Model\TopicArray")
			{
				echo "getAllTopics returned" . get_class($allTopics);
				return FALSE;
			}
			
			foreach($allTopics->get() as $topic)
			{
				$actual = $tl->getTopic($topic->getId());
				
				if($actual->getId() != $topic->getId())
				{
					echo "getTopic error 1: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}

				if($actual->getHeader() != $topic->getHeader())
				{
					echo "getTopic error 2: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}

				if($actual->getUserName() != $topic->getUserName())
				{
					echo "getTopic error 3: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}
				
				if($actual->getDate() != $topic->getDate())
				{
					echo "getTopic error 4: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}
				
				if($actual->getContent() != $topic->getContent())
				{
					echo "getTopic error 5: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}	
				
				if($actual->getUserId() != $topic->getUserId())
				{
					echo "getTopic error 6: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}	

				if($actual->getPostCount() != $topic->getPostCount())
				{
					echo "getTopic error 7: Return value from getAllTopics and getTopic differs";
					return FALSE;
				}																								
			}
			
			//Testar GetTopFiveTopics
			$topFiveTopics = $tl->GetTopFiveTopics();
			
			if(get_class($topFiveTopics) != "Model\TopicArray")
			{
				echo "GetTopFiveTopics returned" . get_class($topFiveTopics);
				return FALSE;
			}
			
			//Testar GetLastAddedTopicId
			$lastAddedTopic = $tl->GetLastAddedTopicId();
			
			if(is_numeric($lastAddedTopic) == FALSE)
			{
				echo "GetLastAddedTopicId returned" . $lastAddedTopic;
				return FALSE;
			}	
			
			//Testar GetTopic
			$topic = $tl->GetTopic($lastAddedTopic);
			
			if(get_class($topic) != "Model\Topic")
			{
				echo "GetLTopic returned" . $topic;
				return FALSE;
			}
			
			//Testar AddTopic
			if($tl->AddTopic("1", "header", "content") != TRUE)
			{
				echo "AddTopic did not return TRUE";
				return FALSE;				
			}
			
			//Testar EditTopic
			$lastAddedTopic = $tl->GetLastAddedTopicId();			
			if($tl->EditTopic("header2", "content", $lastAddedTopic) != TRUE)
			{
				echo "EditTopic did not return TRUE";
				return FALSE;				
			}
			
			//Testar DeleteTopic		
			if($tl->DeleteTopic($lastAddedTopic) != TRUE)
			{
				echo "DeleteTopic did not return TRUE";
				return FALSE;				
			}													
		
			return TRUE;			
			
		}
}

?>